
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

#include <public/globalsensor_tm_store.h>
#include <public/PackMemManager.h>

#define MAX_BYTES_FROM_FILE 32

#define MIN_BYTES_FROM_FILE 1

#define HEADER_BYTES_IN_FRAME 15



byte_t FRAME_HEADER[15]={0xBB, 0xEE, 0xBB, 0xAA, 0xCC, 0xAA, 0xFF, 0xEE, 0xDD, 0xEE, 0xBB, 0xAA, 0xDD, 0xEE, 0xAA};


uint64_t fileSize( const char* filePath ){

uint64_t fsize = 0;
    std::ifstream file( filePath, std::ios::binary );

    fsize = file.tellg();
    file.seekg( 0, std::ios::end );
    fsize = (uint64_t)file.tellg() - fsize;
    file.close();

    return fsize;
}







int main() {

cout << "!!!Hello World this is me!!!" << endl; // prints !!!Hello World!!!


//Global pack Pool
PackPool packPool;
CGlobalSensorTMStore tmStore;

CPackListHandler free_pack_list;
CPackListHandler tm_pack_list;
uint16_t pack_num;
uint32_t total_pack_num=0;


packPool.InitPackagesMemory();




//Utilizar

//************************************************************************
//Test 1 add random
//************************************************************************

do{
//cout << "Hola caracola"<< endl;
pack_num=rand()%100;

packPool.AllocPackages(pack_num,free_pack_list);
total_pack_num+=pack_num;
//cout << pack_num << endl;

tmStore.add_free_pack_list(free_pack_list);

}while(!packPool.IsEmpty());


tmStore.get_free_pack_list(free_pack_list);

if(free_pack_list.CheckPackCounter()!=total_pack_num){

cout << "!!!Error en add_free_pack_list y get_free_pack_list!!!" << endl; // prints !!!Hello World!!!

}

tmStore.add_free_pack_list(free_pack_list);

//***********************************************************************
//Test 2  random store_ssi_tm_frame
//************************************************************************

uint64_t filesize,pendingBytes;
uint8_t nextFrameBytes;
byte_t frame[50];
int x= 1;

//Abrir un archivo binario de test_files ./test_files/....


filesize=fileSize("./test_files/hola.txt" );
pendingBytes=filesize;
cout << filesize <<endl;
ifstream file("./test_files/hola.txt", ios::binary);
ofstream file_salida("./test_files/hola_copy.txt", ios::binary);



while(pendingBytes){

int i=0;

if(pendingBytes>MAX_BYTES_FROM_FILE){

nextFrameBytes = 1 + rand()%MAX_BYTES_FROM_FILE;

}else

nextFrameBytes=pendingBytes;


for(;i < HEADER_BYTES_IN_FRAME; i++){

frame[i]=FRAME_HEADER[i];
}

frame[i]=nextFrameBytes;

i++;

for(;i < (nextFrameBytes+HEADER_BYTES_IN_FRAME+1); i++){

byte_t aux;
aux=file.get();
frame[i]=aux;

}

//Padding with zeroes
for(;i < (MAX_BYTES_FROM_FILE + HEADER_BYTES_IN_FRAME + 1); i++){

frame[i]=0;
}

//
//tmStore.get_tm_pack_list(tm_pack_list);
ssi_link_layer_add_crc_to_data_frame(frame);
tmStore.store_ssi_tm_frame(frame);
pendingBytes-=nextFrameBytes;

}

file.close();

tmStore.get_tm_pack_list(tm_pack_list);
tm_pack_list.ToHeadPack();

CPackHandler currentPack;

uint8_t currentPackIndex=0;
uint8_t framesInThisPack;


while (!tm_pack_list.IsEmpty()){

unsigned char aux;
//unsigned char aux2;
unsigned char frameHeaderIndex;

tm_pack_list.TakeOnePack(currentPack);
currentPackIndex=0;
//currentPack.ReadByte(currentPackIndex, framesInThisPack);
currentPack.ReadByte(currentPackIndex, framesInThisPack);
currentPackIndex++;


while(framesInThisPack){
	frameHeaderIndex=0;
	//cout<<"Frames in this pack"<<framesInThisPack<<endl;
	while (frameHeaderIndex<15){
		currentPack.ReadByte(currentPackIndex, aux);
		if(aux!=FRAME_HEADER[frameHeaderIndex]){
			cout<<"Error"<<endl;
		}
		currentPackIndex++;
		frameHeaderIndex++;
	}

	byte_t LengthOfFrame;
	//el byte que cntiene la longitud
	currentPack.ReadByte(currentPackIndex,LengthOfFrame);
	currentPackIndex++;
	while (LengthOfFrame){

		currentPack.ReadByte(currentPackIndex, aux);
		currentPackIndex++;
		file_salida.put(aux);
		LengthOfFrame--;
	}
	//cout<<"salgo de aqui"<<endl;
	framesInThisPack--;
}
}
//CPackHandler currentPack;
//uint8_t currentPackIndex;
//tm_pack_list
//frame[i]

file_salida.close();

return 0;
}
